package cn.tedu.ivos.base.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

// 注入Spring容器中
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    CustomAuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    CustomAuthenticationFailHandler authenticationFailureHandler;
    @Autowired
    CustomAuthenticationProvider authenticationProvider;
    @Autowired
    CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
    @Autowired
    CustomAccessDeniedHandler customAccessDeniedHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()   // 禁用SCRF(跨域请求伪造)
                .httpBasic()    // 配置HTTP基本认证
                .and().authorizeRequests()  // 配置请求授权.默认禁用所有请求
                .antMatchers(
                        "/doc.html",
                        "/**/*.js",
                        "/**/*.css",
                        "/swagger-resources",
                        "/v2/api-docs"
                ).permitAll()  // 对指定的资源不进行授权检查,允许所有用户访问
                .anyRequest().authenticated()   // 对其他所有请求要求用户必须认证通过
                .and().formLogin()  // 配置表单登录,默认拦截的登录请求地址为Login
                .successHandler(authenticationSuccessHandler)   // 设置认证成功处理器
                .failureHandler(authenticationFailureHandler)   // 设置认证失败处理器
                .permitAll() // 设置所有用户进行登录尝试
                .and().exceptionHandling()  // 当用户尝试访问没有权限资源时,调用自定义的权限拒绝处理器
              //  .accessDeniedHandler(customAccessDeniedHandler)
              //  .authenticationEntryPoint(customAuthenticationEntryPoint) // 设置访问拒绝处理器
                .and().cors()
                .configurationSource(corsConfigurationSource())// 设置跨域配置源
        ;
    }

    /*
     * 配置CORS(跨域资源共享)
     * 他允许所有的请求源,请求方法、请求头和响应头且支持请求凭证
     * */
    private CorsConfigurationSource corsConfigurationSource() {
        //创建一个新的CORS配置对象
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        //允许请求携带凭证，如cookies
        corsConfiguration.setAllowCredentials(true);
        //允许所有的请求头
        corsConfiguration.addAllowedHeader("*");
        //允许所有的请求方法，如GET、POST、PUT、DELETE等
        corsConfiguration.addAllowedMethod("*");
        //允许响应头被客户端访问
        corsConfiguration.addExposedHeader("*");
        //允许来自任何请求源的请求
        corsConfiguration.addAllowedOriginPattern("*");
        //创建一个基于URL的CORS配置源
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        //将之前配置的CORS应用于所有URL
        source.registerCorsConfiguration("/**", corsConfiguration);

        return source;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider);
    }
}
